package com.wsj.security.extend;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class PreAuthenticationProcessingFilter implements Filter, ApplicationContextAware 
{

	public static final String ACEGI_SECURITY_FORM_USERKIND = "j_userkind";

    private FilterConfig filterConfig;
    private boolean initialized = false;
    private Map targetBeans;
    private String targetClass;
    private ApplicationContext applicationContext;

    public String getTargetClass() {
        return targetClass;
    }
    public void setTargetClass(String targetClass) {
        this.targetClass = targetClass;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void destroy() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    
    //将值设置到上下文的UserKindComparisonAware 这个类中
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        try {
			if (!(request instanceof HttpServletRequest)) {
			    throw new ServletException("Can only process HttpServletRequest");
			}

			if (!initialized) {
			    doInit();
			}

			String userKind = obtainUserKind((HttpServletRequest)request);
			for (Iterator it = targetBeans.values().iterator(); it.hasNext();) {
			     UserKindComparisonAware comparison = (UserKindComparisonAware)it.next();
			     comparison.setCurrentUserKind(userKind);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        chain.doFilter(request, response);
    }

    private synchronized void doInit() throws ServletException {
        if ((targetClass == null) || "".equals(targetClass)) {
            throw new ServletException("targetClass must be specified");
        }

        Class _targetClass;

        try {
            _targetClass = Thread.currentThread().getContextClassLoader().loadClass(targetClass);
        } catch (ClassNotFoundException ex) {
            throw new ServletException("Class of type " + targetClass + " not found in classloader");
        }

        targetBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, _targetClass, true, true);

        if (targetBeans.size() == 0) {
            throw new ServletException("Bean context must contain at least one bean of type " + targetClass);
        }

        for (Iterator it = targetBeans.entrySet().iterator(); it.hasNext();) {
              Map.Entry entry = (Map.Entry)it.next();
                if (!(entry.getValue() instanceof UserKindComparisonAware)) {
                    throw new ServletException("Bean '" + entry.getKey() +
                        "' does not implement cn.net.cogent.summer.extension.acegisecurity.providers.UserKindComparisonAware");
                }
        }

        // Set initialized to true at the end of the synchronized method, so
        // that invocations of doFilter() before this method has completed will not
        // cause NullPointerException
        initialized = true;
    }

    protected String obtainUserKind(HttpServletRequest request) {
        return request.getParameter(ACEGI_SECURITY_FORM_USERKIND);
    }


}
